export interface Class<T> extends Function {
    new (...args: any[]): T;
}

/**
 * 类装饰器-自动init，可以自动调用类的静态init方法
 * @param target 类目标
 */
export function AutoInit(target?: any) {
    if (target["init"] != null) {
        target["init"]();
    }
}
//埋点工具
@AutoInit
export abstract class AnalyticsUtil {
    private static readonly NET_MSG_SEND_MGS: string = "NET_MSG_SEND_MGS";
    private static comData: any; //通用数据
    private static msgMap: Map<string, any>;
    /** 初始化*/
    private static init() {
        if (this.msgMap != null) return;
        this.msgMap = new Map();
        if (SystemUtil.isClient()) {
            Event.addServerListener(AnalyticsUtil.NET_MSG_SEND_MGS, (eventName: string, eventDesc: string, jsonData: string) => {
                RoomService.reportLogInfo(eventName, eventDesc, jsonData);
            });
        }
    }
    /**
     * 设置公共数据，每个埋点数据都会附加的字段，由key,value的形式组织
     * @param comData 公共数据
     */
    public static setCommonData(comData: any) {
        AnalyticsUtil.comData = comData;
    }
    /** 根据类型生成一个埋点数据对象
     * @param MsgClass 埋点数据类
     * @returns 数据对象
     */
    public static get<T extends AnalyticsUtil>(MsgClass: Class<T>): T {
        if (this.msgMap == null) {
            this.init();
        }
        if (!AnalyticsUtil.msgMap.has(MsgClass.name)) {
            let msg = new MsgClass();
            msg.data = {};
            if (!AnalyticsUtil.comData) {
                for (const key in AnalyticsUtil.comData) {
                    msg[key] = AnalyticsUtil.comData[key];
                }
            }
            AnalyticsUtil.msgMap.set(MsgClass.name, msg);
        }
        return AnalyticsUtil.msgMap.get(MsgClass.name);
    }
    /**数据说明 */
    abstract desc: string;
    /**数据体 */
    abstract data: any;

    /**
     * 上传埋点数据到潘多拉
     * @param player 在服务端调用时，指定埋点的玩家，如果不写则全房间玩家都上传
     */
    public send(player?: Player) {
        let eventName: string = this.constructor.name.toLowerCase();
        if (eventName.endsWith("$1")) {
            eventName = eventName.substring(0, eventName.length - 2);
        }
        let eventDesc: string = this.desc;
        let jsonData: any = {};
        for (const key in this.data) {
            //潘多拉要求key都要是小写的，value不做要求
            jsonData[key.toLowerCase()] = this.data[key];
        }
        let jsonStr: string = JSON.stringify(jsonData);
        if (SystemUtil.isClient()) {
            RoomService.reportLogInfo(eventName, eventDesc, jsonStr);
        } else {
            if (player == null) {
                Event.dispatchToAllClient(AnalyticsUtil.NET_MSG_SEND_MGS, eventName, eventDesc, jsonStr);
            } else {
                Event.dispatchToClient(player, AnalyticsUtil.NET_MSG_SEND_MGS, eventName, eventDesc, jsonStr);
            }
        }
    }
}
